<template>
  <div class="charts-wrap eeg-wrap">
    <p class="eig-nav-title">Motion</p>
    <div class="eig-card card-top">
      <div class="eig-filter eig-select-wrap">
        <div class="filter-right" style="margin-top: -5px">
          <a-form size="small" :model="seriesForm" layout="inline">
            <div class="wavelength-color-box">
              <div @click="changeWavelength('X')" class="wavelength-color">
                <span
                  :style="{
                    background: checkboxValue.includes('X')
                      ? '#ff0101'
                      : '#D9DADF',
                  }"
                ></span>
                <span>X</span>
              </div>
              <div @click="changeWavelength('Y')" class="wavelength-color">
                <span
                  :style="{
                    background: checkboxValue.includes('Y')
                      ? '#ffba01'
                      : '#D9DADF',
                  }"
                ></span>
                <span>Y</span>
              </div>
              <div @click="changeWavelength('Z')" class="wavelength-color">
                <span
                  :style="{
                    background: checkboxValue.includes('Z')
                      ? '#0073ff'
                      : '#D9DADF',
                  }"
                ></span>
                <span>Z</span>
              </div>
            </div>
            <a-form-item label="min">
              <a-input
                type="number"
                style="width: 100px"
                @change="undateTimeSerie('yAxis')"
                v-model:value="seriesForm.min"
                placeholder="auto"
              />
            </a-form-item>
            <a-form-item label="max">
              <a-input
                type="number"
                style="width: 100px"
                @change="undateTimeSerie('yAxis')"
                v-model:value="seriesForm.max"
                placeholder="auto"
              />
            </a-form-item>
            <a-form-item>
              <a-select
                v-model:value="numSeconds"
                style="width: 100px"
                @change="
                  undateTimeSerie('xAxis');
                  undateTimeSerie('series');
                "
                aria-placeholder="Show Time"
                :options="showTimeOptions"
                size="small"
              ></a-select>
            </a-form-item>
          </a-form>
        </div>
      </div>

      <div class="time-series">
        <lineChart
          id="motionSeriesChart"
          ref="motionSeriesChart"
          :isMerge="true"
          :isShowAllXAxis="true"
          :seriesChannel="checkboxValue"
          :channel="motionChannel"
          :numSeconds="numSeconds"
          :isAutoScaleY="true"
          theme="gray"
          :isShowName="true"
          :colors="motionColors"
          :yMax="1"
          :yMin="0"
          :autoDraw="true"
          style="width: 100%; height: 100%"
        ></lineChart>
      </div>
    </div>
    <p class="eig-nav-title">Metric</p>
    <div class="card-bottom" style="height: 300px; flex: none">
      <div class="eig-card">
        <div class="eig-filter eig-select-wrap" style="padding: 0 0 10px">
          <div class="filter-left">
            <a-select
              size="small"
              v-model:value="stateValue"
              style="width: 140px"
              placeholder="State"
              @change="changeMode"
              :options="channelOptions"
            ></a-select>
          </div>
          <div class="filter-right">
            <a-select
              v-model:value="conNumSeconds"
              style="width: 100px"
              @change="
                changeLineChart('xAxis', 1);
                changeLineChart('series', 1);
              "
              aria-placeholder="Show Time"
              :options="showTimeOptions"
              size="small"
            ></a-select>
          </div>
        </div>
        <lineChart
          id="lineChart1"
          ref="lineChart1"
          :numSeconds="conNumSeconds"
          :channel="concentrationChannel"
          :colors="concentrationColors"
          :isShowName="false"
          :bothGridLines="true"
          theme="gray"
          :yMax="1"
          :hideFps="true"
          :autoDraw="true"
          :yMin="0"
          style="width: 100%; height: 100%"
          :grid="{
            left: 60,
            right: 10,
            middle: 10,
            top: 10,
            bottom: 30,
          }"
        ></lineChart>
      </div>
      <div class="eig-card">
        <div class="eig-filter eig-select-wrap" style="padding: 0 0 10px">
          <div class="filter-left">
            <p class="card-title">HeartRate</p>
          </div>
          <div class="filter-right">
            <a-select
              v-model:value="heartNumSeconds"
              style="width: 100px"
              @change="
                changeLineChart('xAxis', 2);
                changeLineChart('series', 2);
              "
              aria-placeholder="Show Time"
              :options="showTimeOptions"
              size="small"
            ></a-select>
          </div>
        </div>
        <lineChart
          id="lineChart2"
          ref="lineChart2"
          :channel="heartRateChannel"
          :numSeconds="heartNumSeconds"
          :isAutoScaleY="true"
          :autoDraw="true"
          :bothGridLines="true"
          theme="gray"
          :isShowName="false"
          :hideFps="true"
          :colors="heartRateColors"
          :yMax="120"
          :yMin="0"
          style="width: 100%; height: 100%"
          :grid="{
            left: 60,
            right: 10,
            middle: 10,
            top: 10,
            bottom: 30,
          }"
        ></lineChart>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  ref,
  reactive,
  onMounted,
  onBeforeUnmount,
  watch,
  toRaw,
  nextTick,
  getCurrentInstance,
} from "vue";
import type { SelectProps } from "ant-design-vue";
import lineChart from "../../components/lineChart.vue";
import { CustomBluetooth } from "../../utils/bluetooth";
import { CustomDatabase } from "../../utils/db";
let db = new CustomDatabase();
const lineChart1 = ref<any>(null);
const lineChart2 = ref<any>(null);
let bluetooth = new CustomBluetooth();
let eegPkgDataTime: any = [];
let irPkgDataTime: any = [];
let mindRestList: any = [];
let heartRateList: any = [];
let motionSeriesList: any = [];
const checkboxValue = ref(["X", "Y", "Z"]);
let pkgMaxTime = 20;
const showTimeOptionsData = [
  {
    value: 1,
    label: "1 sec",
  },
  {
    value: 5,
    label: "5 sec",
  },
  {
    value: 10,
    label: "10 sec",
  },
  {
    value: 20,
    label: "20 sec",
  },
  // {
  //   value: 30,
  //   label: "30 sec",
  // },
];
const stateValue = ref<string>("Concentration");
const motionChannel = ref(["Accel", "Gyro"]);
const concentrationChannel = ref(["Fp1"]);
const heartRateChannel = ref(["Fp1"]);
const heartRateColors = ref({
  Fp1: "#8FDCFE",
});
const conNumSeconds = ref(10);
const heartNumSeconds = ref(10);
const concentrationColors = ref({
  Fp1: "#8FDCFE",
});
const motionColors = ref({
  X: "#ff0101",
  Y: "#ffba01",
  Z: "#0073ff",
});
const motionSeriesChart = ref<any>(null);
const stateOptionsData = [
  {
    value: "Concentration",
    label: "Concentration",
  },
  {
    value: "Relaxation",
    label: "Relaxation",
  },
];
const channelOptions = ref<SelectProps["options"]>(stateOptionsData);
const showTimeOptions = ref<SelectProps["options"]>(showTimeOptionsData);
const numSeconds = ref(10);
const seriesForm = reactive({
  min: "",
  max: "",
});

onMounted(() => {
  initialize();
});

const mapChanToField = (value) => {
  switch (value) {
    case "Accel":
      return 0;
    case "Gyro":
      return 1;
    default:
      return 0;
  }
};

const mapSeriesToField = (value) => {
  switch (value) {
    case "X":
      return 0;
    case "Y":
      return 1;
    case "Z":
      return 2;
    default:
      return 0;
  }
};

const undateTimeSerie = (type) => {
  switch (type) {
    case "seriesChannel":
      motionSeriesChart.value.setOption({
        seriesChannel: checkboxValue.value,
      });
      break;
    case "series":
      motionSeriesChart.value.setOption({
        series: motionChannel.value.map((motionItem) => {
          return checkboxValue.value.map((item) => {
            return conversionPkgtoTimeSeries(
              mapChanToField(motionItem),
              mapSeriesToField(item),
              item,
              numSeconds.value
            );
          });
        }),
      });
      break;
    case "xAxis":
      motionSeriesChart.value.setOption({
        xAxis: motionChannel.value.map((motionItem) => ({
          max: numSeconds.value,
        })),
      });
      break;
    case "yAxis":
      motionSeriesChart.value.setOption({
        yAxis: motionChannel.value.map((motionItem) => ({
          max: seriesForm.max === "" ? undefined : seriesForm.max,
          min: seriesForm.min === "" ? undefined : seriesForm.min,
        })),
      });
      break;
  }
};

const changeMode = () => {};

const changeWavelength = (value) => {
  if (checkboxValue.value.findIndex((i) => i === value) > -1) {
    checkboxValue.value = checkboxValue.value.filter((i) => i !== value);
  } else {
    checkboxValue.value.push(value);
  }
  undateTimeSerie("seriesChannel");
  undateTimeSerie("series");
};

const initialize = () => {
  mindRestList = [];
  heartRateList = [];
  motionSeriesList = [];
  // 正常模式
  bluetooth.addNotice(bluetoothNotice);
};

// 蓝牙数据通知
const bluetoothNotice = (data) => {
  delete data.psd_relative_percent_s;
  delete data.ir_od_date;
  delete data.loss_data_info_el;
  delete data.baseline_ok;
  delete data.psd_s_multiple;
  delete data.psd_s;
  delete data.psd_relative_s;
  delete data.temperature;
  delete data.error_state;
  handlePkgList(data);
};

// 数据包处理
const handlePkgList = (data) => {
  if (data.pkg_type === 1) {
    if (
      mindRestList.length &&
      mindRestList[mindRestList.length - 1][0] - mindRestList[0][0] >
        pkgMaxTime * 1000
    ) {
      mindRestList.shift();
    }

    mindRestList.push([
      data.time_mark,
      (data.mindfulness_restfulness_s[0][parseState(stateValue.value)] +
        data.mindfulness_restfulness_s[1][parseState(stateValue.value)]) /
        2,
    ]);
    undatelineChartSeries(
      lineChart1,
      concentrationChannel.value[0],
      mindRestList,
      conNumSeconds.value
    );
   
  } else if (data.pkg_type === 2) {
    if (
      heartRateList.length &&
      heartRateList[heartRateList.length - 1][0] - heartRateList[0][0] >
        pkgMaxTime * 1000
    ) {
      heartRateList.shift();
    }

    heartRateList.push([data.time_mark, data.heart_rate]);

    undatelineChartSeries(
      lineChart2,
      heartRateChannel.value[0],
      heartRateList,
      heartNumSeconds.value
    );
  } else if (data.pkg_type === 3) {
    if (
      motionSeriesList.length &&
      motionSeriesList[motionSeriesList.length - 1][0] -
        motionSeriesList[0][0] >
        pkgMaxTime * 1000
    ) {
      motionSeriesList.shift();
    }
    motionSeriesList.push([
      data.time_mark,
      [
        [data.acceleration_x, data.acceleration_y, data.acceleration_z],
        [data.gyro_x, data.gyro_y, data.gyro_z],
      ],
    ]);
    undateTimeSerie("series");
  }
};

const undatelineChartSeries = (refName, name, data, step) => {
  refName.value.setOption({
    series: [
      {
        name,
        data: conversionLineData(data, step),
      },
    ],
  });
};

const changeLineChart = (type, pkg_type) => {
  switch (type) {
    case "series":
      if (pkg_type == 1) {
        undatelineChartSeries(
          lineChart1,
          concentrationChannel.value[0],
          mindRestList,
          conNumSeconds.value
        );
      } else if (pkg_type == 2) {
        undatelineChartSeries(
          lineChart2,
          heartRateChannel.value[0],
          heartRateList,
          heartNumSeconds.value
        );
      }
      break;
    case "xAxis":
      if (pkg_type == 1) {
        lineChart1.value.setOption({
          xAxis: [
            {
              max: conNumSeconds.value,
            },
          ],
        });
      } else if (pkg_type == 2) {
        lineChart2.value.setOption({
          xAxis: [
            {
              max: heartNumSeconds.value,
            },
          ],
        });
      }
      break;
  }
};


const conversionPkgtoTimeSeries = (channel, index, name, step) => {
  if (motionSeriesList.length < 1) return [];
  let maxTimer = motionSeriesList[motionSeriesList.length - 1][0];
  let minTime = maxTimer - step * 1000;
  let sliceData = motionSeriesList.filter(
    (item) => item[0] >= minTime && item[0] <= maxTimer
  );
  let baseTime = 0;
  return {
    name: name,
    data: sliceData.map((item, sliceIndex) => {
      if (sliceIndex !== 0) {
        baseTime += item[0] - sliceData[sliceIndex - 1][0];
      }
      return [baseTime, item[1][channel][index]];
    }),
  };
};

const conversionLineData = (data, step) => {
  if (data.length < 1) return [];
  let maxTimer = data[data.length - 1][0];
  let minTime = maxTimer - step * 1000;
  let sliceData = data.filter(
    (item) => item[0] >= minTime && item[0] <= maxTimer
  );
  let baseTime = 0;
  return sliceData.map((item, sliceIndex) => {
    if (sliceIndex !== 0) {
      baseTime += item[0] - sliceData[sliceIndex - 1][0];
    }
    return [baseTime, item[1]];
  });
};

const parseState = (state: string) => {
  switch (state) {
    case "Concentration":
      return 0;
    case "Relaxation":
      return 1;
  }
  return 0;
};

onBeforeUnmount(() => {
  bluetooth.removeNotice(bluetoothNotice);
});
</script>
<style scoped></style>
